import 'package:flutter_again/models/video_search_params.dart';
import 'package:html/dom.dart';

import '../interfaces/video_platform_parser.dart';
import '../../models/video_platform.dart';
import '../../models/video_search_result.dart';
import '../../models/video_info.dart';
import '../../utils/log.dart';
import 'package:http/http.dart' as http;
import 'package:flutter_again/utils/dom_parse.dart';
import 'package:flutter_again/utils/json.dart';

// ptt解析器
class PttParser implements VideoPlatformParser {
  @override
  final String platformId = 'ptt';
  final client = http.Client();
  @override
  VideoPlatform get platformInfo => VideoPlatform.ptt;
  final categoryMap = {
    '电视剧': 3,
    '电影': 1,
    '动漫': 4,
    '短剧': 66,
    '综艺': 2,
    '体育': 53
  };

  String getUrl(VideoSearchParams params) {
    final rootUrl = platformInfo.rootUrl;
    final category = params.category;
    var url = '$rootUrl/zh-hans';
    // /zh-hans/p/3   /zh-hans/p/3/c/19
    // /zh-hans/p/1   /zh-hans/p/1?area_id=2

    if (params.query != '') {
      url += '/q/${params.query}?page=${params.page}';
    } else if (category != null) {
      int categoryCode = categoryMap[category] ?? 1;
      url += '/p/$categoryCode?page=${params.page}';
    } else {
      url += '?page=${params.page}';
    }
    if (params.year != null) {
      url += '&year=${params.year}';
    }
    return url;
  }

  @override
  search(params) async {
    // 构建爱奇艺特定的搜索API请求
    // 这里使用模拟数据，实际应发送HTTP请求并解析响应
    var url = getUrl(params);
    log.d('url: $url');
    var page = params.page;
    var hasNextPage = false;
    var res = await client.get(Uri.parse(url));
    final document = domParse(res.body);
    final list = getListByParsingHTMLStr(document);
    final pageItemEles = document.querySelectorAll('.pagination .page-item');
    log.d('pageItemEles: $pageItemEles');
    for (final pageItemEle in pageItemEles) {
      if (pageItemEle.classes.contains('prev') || pageItemEle.classes.contains('next')) {
        continue;
      }
      if (pageItemEle.classes.contains('active')) {
        log.d('page: ${int.parse(pageItemEle.text.trim())}');
        page = int.parse(pageItemEle.text.trim());
      } else if (page < int.parse(pageItemEle.text.trim())) {
        hasNextPage = true;
      }
    }
    return VideoSearchResult(
      platform: platformId,
      videos: list,
      currentPage: page,
      hasNextPage: hasNextPage,
    );
  }

  List<VideoInfo> getListByParsingHTMLStr(Document document) {
    final videosEle = document.getElementById('videos');
    final cardList = videosEle?.querySelectorAll('.card');
    List<VideoInfo> list = [];
    if (cardList != null) {
      for (final card in cardList) {
        // var yearText = card.querySelector('.badge');
        
        final cardHeadEles = card.querySelector('.embed-responsive')?.children;
        final linkEle = card.querySelector('.card-body a.visited');
        var path = linkEle?.attributes['href'] ?? '';
        var pathList = path.split('/');
        pathList.insert(pathList.length - 1, 'v');
        path = pathList.join('/');
        var videoInfo = VideoInfo(
          id: '${platformInfo.rootUrl}$path',
          platform: platformId,
          title: linkEle != null ? linkEle.text : '',
          detailUrl: path.isNotEmpty ? '${platformInfo.rootUrl}$path' : null,
        );
        if (cardHeadEles != null) {
          for (var i = 0; i < cardHeadEles.length; i++) {
            switch (i) {
              case 0:
              var bannerUrl = cardHeadEles[0].children[0].attributes['src'];
              if (bannerUrl != null) {
                videoInfo.thumbnailUrl = '${bannerUrl.contains('http') ? '' : platformInfo.rootUrl}$bannerUrl';
              }
                
                // print('banner url: ${cardHeadEles[0].children[0].attributes['src']}');
              break;
              case 1:
                videoInfo.year = cardHeadEles[1].text.trim();
                // print('year: ${cardHeadEles[1].text.trim()}');
              break;
              case 2:
                videoInfo.label = cardHeadEles[2].text;
                // print('total number: ${cardHeadEles[2].text}');
              break;
            }
          }
        }
        list.add(videoInfo);
        // print('url: ${linkEle?.attributes['href']}; name: ${linkEle?.text}');
        // print(card);
      }
    }
    return list;
  }
  
  @override
  getVideoDetail(String url) async {
    // 获取视频详情的实现
    // 这里简化为返回模拟数据
    log.d(url);
    // 加入v
    final res = await client.get(Uri.parse(url));
    final document = domParse(res.body);
    
    final seqLinks = document.querySelectorAll('.seqs .seq');
    // 通过判断有没有剧集，可以判断是否是电视剧还是电影，电影就去
    final List<VideoSeq> seqList = [];
    final videoInfo = VideoInfo(
      id: url,
      platform: platformId,
      title: '',
      thumbnailUrl: '',
      detailUrl: url,
    );
    for (var seqLink in seqLinks) {
      seqList.add(VideoSeq(url: seqLink.attributes['href'] != null ? '${platformInfo.rootUrl}${seqLink.attributes['href']}' :  '', title: seqLink.text));
    }
    videoInfo.videoSeqs = seqList.isNotEmpty ? seqList : null;
    // 从这里开始获取视频url
    // 分为两种情况：1. 电影 2. 剧集
    Document detailDoc;
    if (seqList.isNotEmpty) {
      final res = await client.get(Uri.parse(seqList.first.url));
      detailDoc = domParse(res.body);
    } else {
      final res = await client.get(Uri.parse(url.replaceFirst('/v', '')));
      detailDoc = domParse(res.body);
    }
    final json = detailDoc.querySelector('script[type="application/ld+json"]');
    if (json != null) {
      final detail = jsonParse<Map<String, dynamic>>(json.text);
      videoInfo.description = detail['description'] ?? '';
      videoInfo.videoUrl = detail['contentUrl'];
      videoInfo.title = detail['name'] ?? '';
    }
    return videoInfo;
  }

  @override
  getVideoUrl(String pageUrl) async {
    String? videoUrl;
    final res = await client.get(Uri.parse(pageUrl));
    final doc = domParse(res.body);
    final json = doc.querySelector('script[type="application/ld+json"]');
    if (json != null) {
      final detail = jsonParse<Map<String, dynamic>>(json.text);
      videoUrl = detail['contentUrl'];
    }
    log.d('接收到的页面url: $pageUrl; 获取到的视频url是：$videoUrl');
    return videoUrl;
  }
}